<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<body>
    <!--  
    JavaScript(简称JS)是一个跨平台面向对象的脚本语言
    用来控制网页的行为，使网页可交互

    js代码必须在<script> </script>标签中(script不能自闭合)
    可以放在html任何位置，任何数量，一般放在<body>元素底部
     
    两种引入方式：
    1.内部js：在html页面中使用<script>标签嵌入js代码
    2.外部js：在html页面中使用<script src="文件路径/文件名.js"></script>引入js文件(类似css使用了)
    -->
    <!-- 
    语法
    1.跟java一样，区分大小写，变量名，函数名
    2.每行结尾分号可有可无
    3.注释：跟java一样，单行注释//，多行注释/* */
    4.代码块用{}括起来
    5.运行时候也有栈区，堆区
        栈区：存储基本类型变量和引用类型的变量名(地址)
        堆区：存储引用类型的变量值

    
    输出语句
    1.window.alert("hello world");    //在浏览器弹窗显示（弹窗会阻塞代码执行,window可以省略）
    2.document.write("hello world");  //写入html页面,在浏览器中显示
    3.console.log("hello world");    //在浏览器控制台显示
    -->
    <script>
        alert("hello browser");
        document.write("hello html");
        console.log("hello console");
    </script>
    <!-- 
     变量：
     名字规则与java,c++一样
     1.var 变量名 = 值; 
         // var可以省略,而且可以重复定义，且可以放同类型的值，
         // 作用域是全局，但在函数中作用域是函数体中(var变量是window的属性,所以是全局的)
     2.let 变量名 = 值;  //let不能省略，不能重复定义,作用域是块级作用域，函数中是局部作用域
     3.const 变量名 = 值;  //const不能省略，跟let一样性质但是常量
     -->
    <script>
        {
            var a = "caillo~"
            a = 10;
            let b = "我是b,是let变量";
            const c = 666;
        }
        document.write(a + "<br>");
        document.write("b是" + b + "局部的，不显示呢<br>");
        //当write中有未定义变量，整个语句都不执行
        //而且此<script>块级都不会执行，因为发生了中断
        document.write("我不执行了");
    </script>
    <!-- 
    变量类型，原始类型和引用类型
    1.原始类型：
        number：数字，整数、浮点数，NaN(Not a Number)
        string:单双引号都可以
        boolean: true,false
        null:空对象指针
        undefined:当声明了变量但没有赋值时变量默认是undefined
    2.引用类型：object,array,function
    -->
    <script>
        var b = "caillo~";
        var c = true;
        var d = null;
        var e;
        document.write("a的类型是：" + typeof a + "<br>");    //number
        document.write("b的类型是：" + typeof b + "<br>");    //string
        document.write("c的类型是：" + typeof c + "<br>");    //boolean
        document.write("d的类型是：" + typeof d + "<br>");    //object
        document.write("e的类型是：" + typeof e + "<br><br>");    //undefined
    </script>
    <!-- 
    js中的运算符与java,c++一样
    唯一不同有"=="和"==="
    "=="只比较值(会发生类型转换)，"==="既比较值又比较类型(不会发生类型转换)

    1.字符串类型转成数字类型
        会发生截断，只保留前面有数字部分
        如果字符串前面有非数字字符，转成的结果是NaN
    2.其他类型转化成boolean类型
        数字：0和NaN为false，其他为true
        字符串：空字符串为false，其他为true
        null和undefined：都是false
    -->
    <script>
        a = "123";
        b = 123;
        document.write("这是发生类型转换的：" + (a == b) + "<br>");
        document.write("这是不发生类型转换的：" + (a === b) + "<br>");
        //parseInt用于将字符串转成数字类型
        //parseFloat用于将字符串转成浮点数类型
        document.write(parseInt("123a7981") + "<br>");
        document.write(parseFloat("123.456a7981") + "<br>");
        document.write(parseInt("AAA") + "<br><br>");  
    </script>
    <!-- 
    流程控制语句与java,c++一样
     if else,switch,for,while,do while


     函数
     1.函数声明：function 函数名(){ 函数体 }
     2.函数表达式：var 函数名 = function(){ 函数体 }
     3.箭头函数：var 函数名 = () => { 函数体 }
     4.立即执行函数：(function(){ 函数体 })()
     注：
       函数形参不写类型
       返回值不需要定义类型，直接return即可
    -->
    <script>
        //函数声明
        function fun1(a, b) {
            document.write("我是函数fun1");
            return a + b;
        }
        //函数表达式
        var fun2 = function () {
            document.write("我是函数fun2");
        }
        //箭头函数
        var fun3 = () => {
            document.write("我是函数fun3");
        }
        //立即执行函数(当当前js代码执行到这时候立刻执行)
        (function () { document.write("我是立即执行函数<br>"); })()

        //调用函数
        a = fun1(1, 2, 87, 98); //实参给多个但形参只定义了两个，所以只取前两个
        document.write("fun1(1,2)的结果是：" + a + "<br>");
        fun2();
        fun3();
    </script>

</body>

</html>